#include "stdafx.h"
#include "XGifDrawImpl.h"

#include "DrawUtil.h"
#include "Util.h"
#include "SkinObjMgr.h"
#include "IXGifMgr.h"

IMPLEMENT_SKIN_CLASS(CXGifDrawImpl);

CXGifDrawImpl::CXGifDrawImpl()
{
    m_nCurFrameIndex = 0;
    m_xGif = NULL;
    memset(&m_sizeGif, 0, sizeof(m_sizeGif));
}

CXGifDrawImpl::~CXGifDrawImpl()
{
    ;
}


//////////////////////////////////////////////////////////////////////////
// IXGifDraw
HRESULT CXGifDrawImpl::put_GifPath(IN LPCTSTR szXNC)
{
    if(m_strXNC == szXNC)
        return S_OK;

    ReleaseData();

    XPtr<IXGifMgr> pGifMgr = NULL;
    HRESULT hResult = Util::CreateObject(&pGifMgr);
    CHECK_HRESULT(hResult);

    m_xGif = pGifMgr->LoadGif(szXNC);
    XASSERT_ERROR(m_xGif != NULL, _T("LoadGif Failed"));
    if(m_xGif == NULL)
        return E_FAIL;

    pGifMgr->GetGifSize(m_xGif, &m_sizeGif);

    DWORD dwDelayValueCount = pGifMgr->GetDelayValueCount(m_xGif);
    if(dwDelayValueCount > 0)
    {
        m_DelayValues.resize(dwDelayValueCount);
        hResult = pGifMgr->GetDelayValues(m_xGif, &m_DelayValues[0], dwDelayValueCount);
    }

    DWORD dwFrameCount = pGifMgr->GetFrameCount(m_xGif);
    if(dwFrameCount > 0)
    {
        m_GifFrame.resize(dwFrameCount);
        hResult = pGifMgr->GetFrames(m_xGif, &m_GifFrame[0], dwFrameCount);
    }

    m_strXNC = szXNC;

    return hResult;
}

HRESULT CXGifDrawImpl::get_ImagePath(OUT BSTR* pbstrXNC)
{
    if(::SysReAllocString(pbstrXNC, m_strXNC.GetData()))
        return S_OK;
    return E_FAIL;
}

DWORD CXGifDrawImpl::GetDelayValue()
{
    if(m_DelayValues.size() == 0)
    {
        return 0;
    }
    else if(m_nCurFrameIndex < m_DelayValues.size())
    {
        return m_DelayValues[m_nCurFrameIndex];
    }
    else
    {
        return m_DelayValues[0];
    }
}

DWORD CXGifDrawImpl::GetFrameCount()
{
    return m_GifFrame.size();
}

void CXGifDrawImpl::get_GifSize(OUT SIZE* pGifSize)
{
    memcpy(pGifSize, &m_sizeGif, sizeof(m_sizeGif));
}

void CXGifDrawImpl::NextFrame()
{
    if((++m_nCurFrameIndex) >= m_GifFrame.size())
        m_nCurFrameIndex = 0;
}

//////////////////////////////////////////////////////////////////////////
// IXDraw
HRESULT CXGifDrawImpl::Draw(IN XCANVAS xCanvas, const RECT* lpDes)
{
    RECT rcSrc = {0, 0, m_sizeGif.cx, m_sizeGif.cy};
    return Draw(xCanvas, &rcSrc, lpDes);
}

HRESULT CXGifDrawImpl::Draw(IN XCANVAS xCanvas, IN const RECT* lpSrc, IN const RECT* lpDes)
{
    if(m_nCurFrameIndex < m_GifFrame.size())
        return DrawUtil::DefinedAlphaDraw(xCanvas, m_GifFrame[m_nCurFrameIndex], lpSrc, lpDes);
    else
        return E_FAIL;
}

BOOL CXGifDrawImpl::IsDrawValid()
{
    return (m_GifFrame.size() > 0);
}

void CXGifDrawImpl::EnableColorize(IN BOOL bEnable)
{
    XASSERT_ERROR(FALSE, _T("IXGifDraw::EnableColorize(bEnable) Not Implemented"));
}

void CXGifDrawImpl::Colorize(IN int hue, IN int sat, IN int light)
{
    XASSERT_ERROR(FALSE, _T("IXGifDraw::Colorize(hue, sat, light) Not Implemented"));
}

//////////////////////////////////////////////////////////////////////////
// IBaseObj
void CXGifDrawImpl::OnFinalRelease()
{
    superclass::OnFinalRelease();
    ReleaseData();
}

//////////////////////////////////////////////////////////////////////////
// CXGifDrawImpl
void CXGifDrawImpl::ReleaseData()
{
    if(m_xGif == NULL)
        return;

    XPtr<IXGifMgr> pGifMgr = NULL;
    HRESULT hResult = Util::CreateObject(&pGifMgr);
    if(FAILED(hResult))
        return;

    hResult = pGifMgr->ReleaseGif(m_xGif);
    m_xGif = NULL;

    memset(&m_sizeGif, 0, sizeof(m_sizeGif));
    m_GifFrame.clear();
    m_DelayValues.clear();
    m_nCurFrameIndex = 0;
}
